package cc.md888.app.utils;

import cc.md888.app.exception.BizRuntimeException;
import cc.md888.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.collections4.MapUtils;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
public final class HttpUtils {


    private final static OkHttpClient sClient;

    static {
        sClient = new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(30,TimeUnit.SECONDS)
                .build();

    }


    public static String post(String url,  Map<String, String> headers, Map<String,String> params, String body) {

        try {
            Response response = postForResponse(url, headers, params, body);
            ResponseBody respBoy = response.body();
            return respBoy != null ? respBoy.string() : "";
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw  BizRuntimeException.from(ResultCode.ERROR, "Fail to post http request");
        }
    }


    public static Response postForResponse(String url,  Map<String, String> headers, Map<String,String> params, String body) {
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder() ;
        if(MapUtils.isNotEmpty(params)){
            params.forEach(urlBuilder::addQueryParameter);
        }

        Request.Builder request = new Request.Builder()
                .post(RequestBody.create(MediaType.parse("application/json"), body))
                .url(urlBuilder.build().url());

        if(MapUtils.isNotEmpty(headers)){
            headers.forEach(request::addHeader);
        }

        try {
            Call call = sClient.newCall(request.build());
           return call.execute();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw  BizRuntimeException.from(ResultCode.ERROR, "Fail to post http request");
        }
    }


    public static String get(String url,  Map<String, String> headers, Map<String,String> params) {
        try {
            Response response =  getForResponse(url, headers, params);
            ResponseBody respBoy = response.body();
            return respBoy != null ? respBoy.string() : "";
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw  BizRuntimeException.from(ResultCode.ERROR, "Fail to get http request");
        }
    }


    public static Response getForResponse(String url,  Map<String, String> headers, Map<String,String> params) {
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder() ;
        if(MapUtils.isNotEmpty(params)){
            params.forEach(urlBuilder::addQueryParameter);
        }

        Request.Builder request = new Request.Builder()
                .get()
                .url(urlBuilder.build().url());

        if(MapUtils.isNotEmpty(headers)){
            headers.forEach(request::addHeader);
        }

        try {
            Call call = sClient.newCall(request.build());
            return call.execute();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw  BizRuntimeException.from(ResultCode.ERROR, "Fail to get http request");
        }
    }
}
